﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;

namespace zerobyte_file_finder
{
    public partial class mainform : Form
    {
        public mainform()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
            checkedlistbox_files.MouseDoubleClick += new MouseEventHandler(checkedlistbox_files_MouseDoubleClick);
        }

        void checkedlistbox_files_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo = new System.Diagnostics.ProcessStartInfo() {FileName="explorer.exe", Arguments= "/select," + checkedlistbox_files.SelectedItem.ToString() };
            p.Start();
        }

        #region variables
        List<FileInfo> totalfilelist = new List<FileInfo>();
        List<FileInfo> emptyfiles = new List<FileInfo>();

        int skippedfiles = 0;
        int noaccesstofiles = 0;


        #endregion

        #region buttonactions
        private void button_browse_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                textbox_path.Text = fbd.SelectedPath;
            }
        }

        private void button_startsearch_Click(object sender, EventArgs e)
        {
            totalfilelist.Clear();
            emptyfiles.Clear();
            checkedlistbox_files.Items.Clear();
            ThreadPool.QueueUserWorkItem(new WaitCallback(findzerobytefiles));
        }

        private void button_deletefiles_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure? Don't click yes unless you KNOW WHAT YOU'RE DOING.\ne.g Some programs use it to make lock files, and you will confuse the program if you remove these files.\ndo NOT under any circuimstances remove all files after scanning C:\\. This is guaranteed to fuck up things badly.\n\nAre you SURE?","Hold up!",MessageBoxButtons.YesNo,MessageBoxIcon.Warning) == System.Windows.Forms.DialogResult.Yes)
            {
                ThreadPool.QueueUserWorkItem(new WaitCallback(deleteselectedfiles));
            }
            
        }

        private void button_selectall_Click(object sender, EventArgs e)
        {
            
            for (int i = 0; i < checkedlistbox_files.Items.Count; i++)
            {
                checkedlistbox_files.SetItemChecked(i, true);
            }
        }
        #endregion

        #region functions

        public void deleteselectedfiles(object blargh)
        {
            buttonpanel.Enabled = false;
            label_curaction.Text = "Deleting all selected files..";
            foreach (var filetodelete in checkedlistbox_files.CheckedItems)
            {
                File.Delete(filetodelete.ToString());
            }
            label_curaction.Text = "Done!";
            checkedlistbox_files.Items.Clear();
            MessageBox.Show("List has been emptied to preserve integrity. Don't worry, only the files that you had selected are deleted.");
            buttonpanel.Enabled = true;
        }

        public void findzerobytefiles(object blargh)
        {
            buttonpanel.Enabled = false;
            label_curaction.Text = "Getting files..";
            getfiles(textbox_path.Text);
                label_filestotal.Text = "Files total: " + totalfilelist.Count;
                label_noaccess.Text = "Access denied to files: " + noaccesstofiles.ToString();
                label_skipped.Text = "Files skipped: " + skippedfiles.ToString();
                label_zerobytefiles.Text = "Empty files: " + emptyfiles.Count.ToString();

            label_curaction.Text = "Finding empty files..";
            findemptyfiles();
                label_filestotal.Text = "Files total: " + totalfilelist.Count;
                label_noaccess.Text = "Access denied to files: " + noaccesstofiles.ToString();
                label_skipped.Text = "Files skipped: " + skippedfiles.ToString();
                label_zerobytefiles.Text = "Empty files: " + emptyfiles.Count.ToString();

            label_curaction.Text = "Adding files to listbox..";
                addemptyfilestolistbox();

            label_curaction.Text = "Done!";

            buttonpanel.Enabled = true;
        }

        void findemptyfiles()
        {
            foreach (var file in totalfilelist)
            {
                try
                {

                    if (file.Length < 1)
                    {
                        emptyfiles.Add(file);
                    }
                }
                catch (UnauthorizedAccessException)
                {
                    noaccesstofiles++;
                }
                catch (Exception)
                {
                    skippedfiles++;
                }
                if ((emptyfiles.Count % 100) == 0)
                {
                    label_filestotal.Text = "Files total: " + totalfilelist.Count;
                    label_noaccess.Text = "Access denied to files: " + noaccesstofiles.ToString();
                    label_skipped.Text = "Files skipped: " + skippedfiles.ToString();
                    label_zerobytefiles.Text = "Empty files: " + emptyfiles.Count.ToString();
                }
            }
        }

        void getfiles(string path)
        {
            try
            {
                Directory.GetDirectories(path).ToList().ForEach(s => getfiles(s));
                Directory.GetFiles(path).ToList().ForEach(s => totalfilelist.Add(new FileInfo(s)));
                if ((totalfilelist.Count % 100) == 0)
                {
                    label_filestotal.Text = "Files total: " + totalfilelist.Count;
                    label_noaccess.Text = "Access denied to files: " + noaccesstofiles.ToString();
                    label_skipped.Text = "Files skipped: " + skippedfiles.ToString();
                }
            }
            catch (UnauthorizedAccessException)
            {
                noaccesstofiles++;
                label_filestotal.Text = "Files total: " + totalfilelist.Count;
                label_noaccess.Text = "Access denied to files: " + noaccesstofiles.ToString();
                label_skipped.Text = "Files skipped: " + skippedfiles.ToString();
            }
            catch (Exception)
            {
                skippedfiles++;
            }
        }

        void addemptyfilestolistbox()
        {
            foreach (var emptyfile in emptyfiles)
            {
                if (checkedlistbox_files.InvokeRequired)
                {
                    curemptyfile = emptyfile;
                    delicious del = new delicious(addlistboxitem);
                    checkedlistbox_files.Invoke(del);
                }
                else
                {
                    checkedlistbox_files.Items.Add(emptyfile.FullName);
                }
            }
        }
        #endregion

        #region delegates
        delegate void delicious();

        FileInfo curemptyfile;
        void addlistboxitem()
        {
            checkedlistbox_files.Items.Add(curemptyfile.FullName);
        }

        #endregion

    }
}
